home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-13 | 19.1 KB | 693 lines | [TEXT/MPS ] |
- // tumbler_podium.c -- this contains the podium specific routines for the tumbler app
- //
- //
-
-
- #ifdef PODIUM_APP
-
- #include "QD3D.h"
-
- #include <Drag.h>
- #include <Events.h>
- #include <Controls.h>
- #include <ToolUtils.h>
- #include <Windows.h>
-
- #include "QD3DView.h"
- #include "QD3DDrawContext.h"
- #include "QD3DDrawContext.h"
- #include "QD3DPick.h"
- #include "QD3DGroup.h"
- #include "QD3DTransform.h"
- #include "QD3DLight.h"
- #include "QD3DMath.h"
-
-
- #include <QuickDraw.h>
- #include <QDOffscreen.h>
-
-
- #include "tumbler_Document.h"
- #include "tumbler_Camera.h"
- #include "tumbler_podium.h"
- #include "tumbler_offscreen.h"
- #include "tumbler_drag.h"
-
-
- static CursHandle objectCursor, zoomInCursor, zoomOutCursor, handCursor;
-
-
- static TQ3Object DoHitTest(DocumentPtr theDocument);
- static short PointInRect(Point *point, Rect *rect);
-
- // Used in Tumber_AEVT.c
- void Podium_UpdateDrawContextFromDropRect( DocumentPtr theDocument ) ;
-
- //------------------------------------------------------------------------------------
- void Podium_UpdateDrawContextFromDropRect( DocumentPtr theDocument )
- {
-
- Rect frameRect ;
- PixMapHandle hPixMap ;
- Rect srcRect ;
- TQ3PixmapDrawContextData myDrawContextData ;
-
- frameRect = theDocument->dropArea ;
-
- // if the drop area for the doc is the same as the GWorld's rect
- // then we don't need to do anything, if they have changes we need
- // to update the drawcontext
-
- if(!EqualRect(&frameRect,&theDocument->geometriesOffscreen->portRect)) {
- TQ3DrawContextObject theDrawContext ;
- OSErr theErr ;
-
- if((theErr = UpdateGWorld( &theDocument->geometriesOffscreen, 32, &frameRect, nil, nil, 0L )) == noErr
- // && (theErr = UpdateGWorld( &theDocument->maskOffscreen, 1, &frameRect, nil, nil, 0L )) == noErr
- ) {
-
- theDrawContext = TumblerDocument_NewPixmapDrawContext( theDocument ) ;
- Q3View_SetDrawContext(theDocument->theView, theDrawContext);
- Q3Object_Dispose(theDrawContext);
-
- AdjustCamera(theDocument,
- theDocument->geometriesOffscreen->portRect.right - theDocument->geometriesOffscreen->portRect.left,
- theDocument->geometriesOffscreen->portRect.bottom - theDocument->geometriesOffscreen->portRect.top);
- }
- }
- }
-
-
-
-
-
- static void MouseMoved(
- DocumentPtr theDocument,
- long oldX,
- long oldY,
- long newX,
- long newY)
- {
- float scaleFactor = 256.0;
- unsigned long winWidth, winHeight;
- TQ3Matrix4x4 currentMatrix, tmp, newMatrix;
- TQ3BoundingBox viewBBox;
- TQ3Point3D modelCenter;
-
- /*
- * Find the bounding box for the group.
- * We'll use the center of the box as the point about which to rotate
- * (the old method always rotated about the world-space origin).
- */
-
- /*
- * Get the width and height of the *current* window.
- * This is done so that mouse motion in a window has an effect
- * relative to the size of the window.
- */
- winWidth = theDocument->theWindow->portRect.right - theDocument->theWindow->portRect.left;
- winHeight = theDocument->theWindow->portRect.bottom - theDocument->theWindow->portRect.top;
-
- GetGroupBBox(theDocument->theView, theDocument->documentGroup, NULL, &viewBBox);
-
- /*
- * The "to" point is the center of the view bounding box
- */
- {
- float weights[2] = { 0.5, 0.5 };
- TQ3Point3D points[2];
-
- points[0] = viewBBox.min;
- points[1] = viewBBox.max;
-
- Q3Point3D_AffineComb(points, weights, 2, &modelCenter);
- }
-
- /*
- * Make a new rotation matrix, rotating about the center of the view
- * bbox.
- */
- {
- float xRot, yRot, zRot;
-
- xRot = yRot = zRot = 0.0;
-
- xRot = Q3Math_DegreesToRadians((float)(newY - oldY) / winHeight * scaleFactor);
- yRot = Q3Math_DegreesToRadians((float)(newX - oldX) / winWidth * scaleFactor);
-
- if ((xRot != 0.0) || (yRot != 0.0)){
- Q3Matrix4x4_SetRotateAboutPoint(&tmp, &modelCenter, xRot, yRot, zRot);
- Q3Matrix4x4_Multiply(&theDocument->modelRotation, &tmp, &theDocument->modelRotation);
- }
- }
-
- }
-
-
- static short PointInRect(Point *point, Rect *rect)
- {
- if( point->h > rect->left && point->h < rect->right ) {
- if( point->v > rect->top && point->v < rect->bottom ) {
- return(1);
- } else {
- return(0);
- }
- } else {
- return(0);
- }
- }
-
-
- static Boolean PtOnHandles(Point *newMouse, Rect *location, short *whichHandle)
- {
- Rect handlesRect;
-
- handlesRect.left = location->left - 4;
- handlesRect.top = location->top - 4;
- handlesRect.right = location->left;
- handlesRect.bottom = location->top;
-
- if( PointInRect(newMouse, &handlesRect) ) {
- *whichHandle = LeftTopHandle;
- return(true);
- }
-
- handlesRect.left = location->right;
- handlesRect.right = location->right + 4;
-
- if( PointInRect(newMouse, &handlesRect) ) {
- *whichHandle = RightTopHandle;
- return(true);
- }
-
- handlesRect.left = location->right;
- handlesRect.right = location->right + 4;
- handlesRect.top = location->bottom;
- handlesRect.bottom = location->bottom + 4;
-
- if( PointInRect(newMouse, &handlesRect) ) {
- *whichHandle = RightBottomHandle;
- return(true);
- }
-
- handlesRect.left = location->left - 4;
- handlesRect.right = location->left;
-
- if( PointInRect(newMouse, &handlesRect) ) {
- *whichHandle = LeftBottomHandle;
- return(true);
- }
- return(false);
- }
-
- static void DrawHandles(Rect *location)
- {
- Rect handlesRect;
-
- handlesRect.left = location->left - 4;
- handlesRect.top = location->top - 4;
- handlesRect.right = location->left;
- handlesRect.bottom = location->top;
-
- PaintRect(&handlesRect);
-
- handlesRect.left = location->right;
- handlesRect.right = location->right + 4;
-
- PaintRect(&handlesRect);
-
- handlesRect.left = location->right;
- handlesRect.right = location->right + 4;
- handlesRect.top = location->bottom;
- handlesRect.bottom = location->bottom + 4;
-
- PaintRect(&handlesRect);
-
- handlesRect.left = location->left - 4;
- handlesRect.right = location->left;
-
- PaintRect(&handlesRect);
-
- PenSize(2,2);
- MoveTo(location->left - 2, location->top - 2);
- LineTo(location->right, location->top - 2);
- LineTo(location->right, location->bottom);
- LineTo(location->left - 2, location->bottom);
- LineTo(location->left - 2, location->top - 2);
- //FrameRect(location);
- }
-
- /*
- * hit test a click in the document.
- */
-
- static TQ3Object DoHitTest(DocumentPtr theDocument)
- {
- TQ3WindowPointPickData withData;
- unsigned long numPicked;
- // TQ3RendererObject saveRenderer;
- TQ3PickObject pickObject;
- // TQ3DrawContextObject drawCtx;
-
- withData.data.sort = kQ3PickSortNone;
- withData.data.numHitsToReturn= 1;
- withData.data.mask = kQ3PickDetailMaskObject;
-
- withData.point.x = theDocument->mouseLocation.h - theDocument->dropArea.left;
- withData.point.y = theDocument->mouseLocation.v - theDocument->dropArea.top;
-
- withData.vertexTolerance = withData.edgeTolerance = 3;
- // this field gone in beta: withData.view = theDocument->theView;
-
- pickObject = Q3WindowPointPick_New(&withData);
-
- //Q3View_GetRenderer(theDocument->theView, &saveRenderer);
- //Q3View_GetDrawContext(theDocument->theView, &drawCtx);
-
- //Q3View_SetRendererByType(theDocument->theView, kQ3RendererTypeGeneric);
- //Q3Object_Dispose(drawCtx);
-
- Q3View_StartPicking(theDocument->theView, pickObject );
- do {
- Q3DisplayGroup_Submit(theDocument->documentGroup, theDocument->theView);
- } while (Q3View_EndPicking(theDocument->theView) == kQ3ViewStatusRetraverse);
-
- // Q3View_SetRenderer(theDocument->theView, saveRenderer);
-
- // Q3Object_Dispose(saveRenderer);
-
- if (Q3Pick_GetNumHits(pickObject, &numPicked) == kQ3Success && (numPicked != 0)) {
- TQ3HitData hitData;
-
- // used to be: ErPick_GetFirstHit(pickObject, &hitData);
- Q3Pick_GetHitData( pickObject, 1, &hitData );
- Q3Object_Dispose(pickObject);
- return(hitData.object);
- } else {
- Q3Object_Dispose(pickObject);
- return(NULL);
- }
-
- }
-
- /*
- * DoContent handles mouseDown events in the content region of a document window.
- *
- * (1) If the mouseDown is on a control, handle the click by calling TrackControl.
- *
- * (2) If the mouseDown is on a draggable object (the document's hiliteRgn) and a
- * successful drag occurs, no further processing is necessary.
- *
- * (3) If the mouseDown is on a draggable object and the mouse is released without
- * dragging, set the insertion point to the original mouseDown location by calling
- * TEClick with the mouseDown information.
- *
- * (4) If the mouseDown is not on a draggable object and within the viewRect of the
- * TextEdit field, call TEClick to handle the mouseDown.
- */
-
- void Podium_DoContent(DocumentPtr theDocument, EventRecord *theEvent)
-
- { short thePart;
- Point thePoint;
- ControlHandle theControl;
-
- SetPort(theDocument->theWindow);
- thePoint = theEvent->where;
-
- if( theDocument->documentGroup ) {
- Point newMouse, offset;
- short whichHandle;
-
- GetMouse(&newMouse);
- theDocument->mouseLocation = newMouse;
-
- /* First check for resize */
- if( theDocument->currentlySelectedObject && PtOnHandles(&newMouse, &theDocument->dropArea, &whichHandle) ) {
- Rect previousRect;
- Rect frameRect;
- Point oldMouse;
- TQ3Boolean needRedraw;
-
- PenMode(srcXor);
- PenSize(2,2);
- frameRect = previousRect = theDocument->dropArea;
-
- oldMouse = theDocument->mouseLocation;
- switch( whichHandle ){
- case LeftTopHandle:
-
- offset.h = newMouse.h - frameRect.left;
- offset.v = newMouse.v - frameRect.top;
-
- while (WaitMouseUp()) {
- GetMouse(&newMouse);
- if (newMouse.h >= oldMouse.h + 2 || newMouse.h <= oldMouse.h - 2 ||
- newMouse.v >= oldMouse.v + 2 || newMouse.v <= oldMouse.v - 2) {
- needRedraw = kQ3True;
- frameRect.left = newMouse.h - offset.h;
- frameRect.top = newMouse.v - offset.v;
- DrawHandles(&previousRect);
- DrawHandles(&frameRect);
- previousRect = frameRect;
- }
- }
- break;
- case RightTopHandle:
-
- offset.h = newMouse.h - frameRect.right;
- offset.v = newMouse.v - frameRect.top;
-
- while (WaitMouseUp()) {
- GetMouse(&newMouse);
- if (newMouse.h >= oldMouse.h + 2 || newMouse.h <= oldMouse.h - 2 ||
- newMouse.v >= oldMouse.v + 2 || newMouse.v <= oldMouse.v - 2) {
- needRedraw = kQ3True;
- frameRect.right = newMouse.h - offset.h;
- frameRect.top = newMouse.v - offset.v;
- DrawHandles(&previousRect);
- DrawHandles(&frameRect);
- previousRect = frameRect;
- }
- }
- break;
- case LeftBottomHandle:
-
- offset.h = newMouse.h - frameRect.left;
- offset.v = newMouse.v - frameRect.bottom;
-
- while (WaitMouseUp()) {
- GetMouse(&newMouse);
- if (newMouse.h >= oldMouse.h + 2 || newMouse.h <= oldMouse.h - 2 ||
- newMouse.v >= oldMouse.v + 2 || newMouse.v <= oldMouse.v - 2) {
- needRedraw = kQ3True;
- frameRect.left = newMouse.h - offset.h;
- frameRect.bottom = newMouse.v - offset.v;
- DrawHandles(&previousRect);
- DrawHandles(&frameRect);
- previousRect = frameRect;
- }
- }
- break;
- case RightBottomHandle:
-
- offset.h = newMouse.h - frameRect.right;
- offset.v = newMouse.v - frameRect.bottom;
-
- while (WaitMouseUp()) {
- GetMouse(&newMouse);
- if (newMouse.h >= oldMouse.h + 2 || newMouse.h <= oldMouse.h - 2 ||
- newMouse.v >= oldMouse.v + 2 || newMouse.v <= oldMouse.v - 2) {
- needRedraw = kQ3True;
- frameRect.right = newMouse.h - offset.h;
- frameRect.bottom = newMouse.v - offset.v;
- DrawHandles(&previousRect);
- DrawHandles(&frameRect);
- previousRect = frameRect;
- }
- }
- break;
- }
-
- theDocument->dropArea = frameRect;
-
- if( needRedraw == kQ3True ) {
- Podium_UpdateDrawContextFromDropRect( theDocument ) ;
- DrawOffscreen(theDocument);
- DrawOnscreen(theDocument);
-
- }
-
- PenMode(srcXor);
- PenSize(2,2);
- PenPat(&qd.black);
- DrawHandles(&frameRect);
- /* is it in content */
- } else if( PtInRect(newMouse, &theDocument->dropArea) ) {
- // TQ3Object newPick;
- // if(( newPick = DoHitTest(theDocument)) != NULL) {
- if( theDocument->selected == kQ3False) {
- PenMode(srcXor);
- PenSize(2,2);
- PenPat(&qd.black);
- DrawHandles(&theDocument->dropArea);
- }
-
- theDocument->currentlySelectedObject = theDocument->documentGroup ;
-
- if( theEvent->modifiers & shiftKey )
- SetCursor(*zoomInCursor);
- else if( theEvent->modifiers & cmdKey )
- SetCursor(*zoomOutCursor);
- else
- SetCursor(*objectCursor);
-
- if( theEvent->modifiers & shiftKey ) {
- TQ3Matrix4x4 tmp;
-
- Q3Matrix4x4_SetScale(&tmp, 1.2, 1.2, 1.2);
- while (WaitMouseUp()) {
- Q3Matrix4x4_Multiply(&tmp, &theDocument->modelRotation, &theDocument->modelRotation);
- DrawOffscreen( theDocument ) ;
- DrawOnscreen( theDocument ) ;
- }
- } else if( theEvent->modifiers & cmdKey ) {
- TQ3Matrix4x4 tmp;
-
- Q3Matrix4x4_SetScale(&tmp, 0.83333, 0.83333, 0.83333);
- while (WaitMouseUp()) {
- Q3Matrix4x4_Multiply(&tmp, &theDocument->modelRotation, &theDocument->modelRotation);
- DrawOffscreen(theDocument);
- DrawOnscreen( theDocument ) ;
- }
- } else if( theEvent->modifiers & controlKey ) {
-
- Point oldMouse;
- Point newMouse;
- long mouseChanged = 0;
- long dx, dy, x, y, oldX, oldY;
- float width, height;
- float xRot, yRot;
-
- SetCursor(*handCursor);
- GetMouse(&newMouse); // get the mouse in local co-ordinates,
- // local to the current GrafPort
-
- oldX = newMouse.h;
- oldY = newMouse.v;
-
- width = theDocument->geometriesOffscreen->portRect.right - theDocument->geometriesOffscreen->portRect.left;
- height = theDocument->geometriesOffscreen->portRect.bottom - theDocument->geometriesOffscreen->portRect.top;
-
- while (WaitMouseUp()) {
-
- GetMouse(&newMouse); // get the mouse in local co-ordinates,
- // local to the current GrafPort
-
- dx = newMouse.v - oldY;
- dy = newMouse.h - oldX;
-
- if ((dx != 0) || (dy != 0)) {
- TQ3Matrix4x4 tempMatrix;
-
- xRot = ((float) dx * kQ3Pi) / width;
- yRot = ((float) dy * kQ3Pi) / height;
-
- if ((xRot != 0.0) || (yRot != 0.0)) {
- Q3Matrix4x4_SetRotate_XYZ(&tempMatrix, xRot, yRot, 0.0);
- Q3Matrix4x4_Multiply(&theDocument->modelRotation, &tempMatrix, &theDocument->modelRotation);
-
- mouseChanged = 1;
- DrawOffscreen(theDocument);
- DrawOnscreen( theDocument ) ;
- }
- }
- oldX = newMouse.h; oldY = newMouse.v;
- }
-
- if( mouseChanged ) {
- theDocument->rotationDir.x = xRot;
- theDocument->rotationDir.y = yRot;
- }
- } else {
- Rect previousRect;
- Rect frameRect;
- Point oldMouse;
- TQ3Boolean needRedraw;
- long height, width;
-
- PenMode(srcXor);
- PenSize(2,2);
- frameRect = previousRect = theDocument->dropArea;
- height = frameRect.bottom - frameRect.top;
- width = frameRect.right - frameRect.left;
-
- offset.h = newMouse.h - frameRect.left;
- offset.v = newMouse.v - frameRect.top;
-
- oldMouse = theDocument->mouseLocation;
- while (WaitMouseUp()) {
- GetMouse(&newMouse);
- if (newMouse.h >= oldMouse.h + 2 || newMouse.h <= oldMouse.h - 2 ||
- newMouse.v >= oldMouse.v + 2 || newMouse.v <= oldMouse.v - 2) {
- needRedraw = kQ3True;
- frameRect.left = newMouse.h - offset.h;
- frameRect.top = newMouse.v - offset.v;
- frameRect.right = frameRect.left + width;
- frameRect.bottom = frameRect.top + height;
- DrawHandles(&previousRect);
- DrawHandles(&frameRect);
- previousRect = frameRect;
- }
- }
-
- theDocument->dropArea = frameRect;
-
- if( needRedraw == kQ3True ) {
- Podium_UpdateDrawContextFromDropRect( theDocument ) ;
- DrawOffscreen(theDocument);
- DrawOnscreen(theDocument);
-
- }
- PenMode(srcXor);
- PenSize(2,2);
- PenPat(&qd.black);
- DrawHandles(&frameRect);
- }
- } else {
- if( theDocument->selected == kQ3True) {
- theDocument->currentlySelectedObject = NULL;
- theDocument->selected = kQ3False;
- PenMode(srcXor);
- PenSize(2,2);
- PenPat(&qd.black);
- DrawHandles(&theDocument->dropArea);
- }
- SetCursor(&qd.arrow);
- }
- }
- else {
-
- if( theDocument->currentlySelectedObject ) {
- theDocument->currentlySelectedObject = NULL;
- PenMode(srcXor);
- PenSize(2,2);
- DrawHandles(&theDocument->dropArea);
- SetCursor(&qd.arrow);
- }
- }
- }
-
-
- /*
- * DoBackgroundContent handles mouseDown events in the content region of a document window
- * when the window is not frontmost. The following bullet items describe how this background
- * mouseDown event is handled:
- *
- * (1) If the mouseDown is not in a draggable object (not in the document's hiliteRgn) call
- * SelectWindow to bring the window to the front as usual.
- *
- * (2) If the mouseDown is in a draggable object and the mouse is released without
- * dragging, call SelectWindow when the mouse is released.
- *
- * (3) If the mouseDown is in a draggable object and a successful drag occurs, SelectWindow
- * should only be called if the drop occurred in the same window (the DragText function
- * calls SelectWindow in this case).
- */
- void Podium_DoBackgroundContent(DocumentPtr theDocument, EventRecord *theEvent)
-
- { short thePart;
- Point thePoint;
- ControlHandle theControl;
- RgnHandle tempRgn = NewRgn(); // Nick this needs to be the BBox of the group
-
- SetPort(theDocument->theWindow);
- thePoint = theEvent->where;
- GlobalToLocal(&thePoint);
-
- RectRgn(tempRgn, &theDocument->geometriesOffscreen->portRect);
-
- if (PtInRgn(thePoint,tempRgn)) {
- if (! DoDragObjects(theDocument, theEvent, tempRgn)) {
- SelectWindow(theDocument->theWindow);
- }
- }
- else {
- SelectWindow(theDocument->theWindow);
- }
-
- DisposeRgn(tempRgn);
- }
-
-
-
-
- /*
- * DoIdle get called repetitively while the application is not doing
- * anything.
- */
-
- void Podium_DoIdle(EventRecord *theEvent)
- {
- WindowPtr theWindow;
- DocumentPtr theDocument;
-
- if ((theWindow = FrontWindow()) != nil) {
- if ((theDocument = GetDocumentFromWindow(theWindow)) != nil) {
- SetPort(theDocument->theWindow);
-
- if( theDocument->documentGroup ) {
- Point mouseLocation;
-
- GetMouse(&mouseLocation);
-
- theDocument->mouseLocation = mouseLocation;
-
- if( PointInRect(&theDocument->mouseLocation, &theDocument->dropArea) ) {
- if(/*DoHitTest(theDocument)*/1) {
- if( theEvent->modifiers & shiftKey) {
- SetCursor(*zoomInCursor);
- } else if( theEvent->modifiers & cmdKey) {
- SetCursor(*zoomOutCursor);
- } else if( theEvent->modifiers & controlKey) {
- SetCursor(*handCursor);
- } else {
- SetCursor(*objectCursor);
- }
- } else {
- SetCursor(&qd.arrow);
- }
- } else {
- SetCursor(&qd.arrow);
- }
-
- if( theDocument->animateModel == kQ3True) {
- TQ3Matrix4x4 tmp;
-
- if( theDocument->rotationDir.x == 0.0 && theDocument->rotationDir.y == 0.0 ) {
- Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.03, 0.08, 0.0);
- Q3Matrix4x4_Multiply(&theDocument->modelRotation, &tmp, &theDocument->modelRotation);
- } else {
- Q3Matrix4x4_SetRotate_XYZ(&tmp, theDocument->rotationDir.x, theDocument->rotationDir.y, 0.0);
- Q3Matrix4x4_Multiply(&theDocument->modelRotation, &tmp, &theDocument->modelRotation);
- }
- DrawOffscreen(theDocument);
- DrawOnscreen(theDocument);
- }
- }
- }
- }
- }
-
- void Podium_Init(void)
- {
- objectCursor = GetCursor(132);
- zoomInCursor = GetCursor(133);
- zoomOutCursor = GetCursor(134);
- handCursor = GetCursor(130);
- }
-
-
-
- #endif /* PODIUM_APP */
-